﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Blog_BLL
{
    /// <summary>
    /// 工具类
    /// </summary>
    public static class ToosBLL
    {
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="strString">字符串</param>
        /// <returns></returns>
        public static string GetMd5Hash(this String strString)
        {
            if (strString == null)
            {
                return null;
            }

            System.Security.Cryptography.MD5 md5Hash = System.Security.Cryptography.MD5.Create();

            // 将输入字符串转换为字节数组并计算哈希数据 
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(strString));

            // 创建一个 Stringbuilder 来收集字节并创建字符串 
            StringBuilder sBuilder = new StringBuilder();

            // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串 
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // 返回十六进制字符串 
            return sBuilder.ToString();
        }
        public static string ObjToJson<T>(this T data)
        {
            try
            {

                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(data.GetType());
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    serializer.WriteObject(ms, data);
                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// 过滤sql非法字符,防止sql注入
        /// </summary>
        /// <param name="sInput"></param>
        /// <returns></returns>
        public static string Filter(this string source)
        {
            //单引号替换成两个单引号
            source = source.Replace("'", "''");
            //半角封号替换为全角封号，防止多语句执行
            source = source.Replace(";", "；");
            //半角括号替换为全角括号
            source = source.Replace("(", "（");
            source = source.Replace(")", "）");
            ///////////////要用正则表达式替换，防止字母大小写得情况////////////////////
            //去除执行存储过程的命令关键字
            source = source.Replace("Exec", "");
            source = source.Replace("Execute", "");
            //去除系统存储过程或扩展存储过程关键字
            source = source.Replace("xp_", "x p_");
            source = source.Replace("sp_", "s p_");
            //防止16进制注入
            source = source.Replace("0x", "0 x");
            //不安全字符
            source = source.Replace("'", "");
            source = source.Replace("\"", "");
            source = source.Replace("&", "&");
            source = source.Replace("<", "<");
            source = source.Replace(">", ">");
            source = source.Replace("delete", "");
            source = source.Replace("update", "");
            source = source.Replace("insert", "");
            return source;
        }
        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="encodeType">加密采用的编码方式</param>
        /// <param name="source">待加密的明文</param>
        /// <returns></returns>
        public static string Base64Encode(this string source, Encoding encodeType)
        {
            string encode = string.Empty;
            byte[] bytes = encodeType.GetBytes(source);
            try
            {
                encode = Convert.ToBase64String(bytes);
            }
            catch
            {
                encode = source;
            }
            return encode;
        }
        /// <summary>
        /// Base64解密
        /// </summary>
        /// <param name="encodeType">解密采用的编码方式，注意和加密时采用的方式一致</param>
        /// <param name="result">待解密的密文</param>
        /// <returns>解密后的字符串</returns>
        public static string Base64Decode(this string result, Encoding encodeType)
        {
            string decode = string.Empty;
            byte[] bytes = Convert.FromBase64String(result);
            try
            {
                decode = encodeType.GetString(bytes);
            }
            catch
            {
                decode = result;
            }
            return decode;
        }
        /// <summary>
        /// Convert a List{T} to a DataTable.
        /// </summary>
        public static DataTable ToDataTable<T>(List<T> items)
        {
            var tb = new DataTable(typeof(T).Name);

            PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo prop in props)
            {
                Type t = GetCoreType(prop.PropertyType);
                tb.Columns.Add(prop.Name, t);
            }
            foreach (T item in items)
            {
                var values = new object[props.Length];

                for (int i = 0; i < props.Length; i++)
                {
                    values[i] = props[i].GetValue(item, null);
                }

                tb.Rows.Add(values);
            }

            return tb;
        }
        /// <summary>
        /// Determine of specified type is nullable
        /// </summary>
        public static bool IsNullable(Type t)
        {
            return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
        }
        /// <summary>
        /// Return underlying type if type is Nullable otherwise return the type
        /// </summary>
        public static Type GetCoreType(Type t)
        {
            if (t != null && IsNullable(t))
            {
                if (!t.IsValueType)
                {
                    return t;
                }
                else
                {
                    return Nullable.GetUnderlyingType(t);
                }
            }
            else
            {
                return t;
            }
        }
        /// <summary>
        /// 去除字符串html标签
        /// </summary>
        /// <param name="html">html</param>
        /// <param name="length">取文章前length个字符(默认50)</param>
        /// <returns></returns>
        public static string ReplaceHtmlTag(this string html, int length = 50)
        {
            string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", "");
            strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", "");

            if (length > 0 && strText.Length > length)
                return strText.Substring(0, length);

            return strText;
        }
        /// <summary>   
        /// 取得HTML中所有图片的 URL。   
        /// </summary>   
        /// <param name="sHtmlText">HTML代码</param>   
        /// <returns>图片的URL列表</returns>   
        public static string[] GetHtmlImageUrlList(this string sHtmlText)
        {
            // 定义正则表达式用来匹配 img 标签   
            Regex regImg = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase);

            // 搜索匹配的字符串   
            MatchCollection matches = regImg.Matches(sHtmlText);
            int i = 0;
            string[] sUrlList = new string[matches.Count];

            // 取得匹配项列表   
            foreach (Match match in matches)
                sUrlList[i++] = match.Groups["imgUrl"].Value;
            return sUrlList;
        }
        /// <summary>
        /// 破解防盗链图片
        /// </summary>
        /// <param name="url"></param>
        public static string CrackFdl(this string url)
        {
            if (url.Contains("http") || url.Contains("https"))
            {
                string[] filenames = url.Split('/')[url.Split('/').Length-1].Split('.');
                string fileName = Guid.NewGuid().ToString() + (filenames.Length == 1 ? ".jpg" : "." + filenames[filenames.Length - 1]);
                string filePath = AppDomain.CurrentDomain.BaseDirectory + "Upload/Images/BlogContent/" + fileName;
                //HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
                //webrequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/QVOD, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
                //webrequest.Headers.Add("Accept-Encoding", "gzip, deflate");
                //webrequest.Headers.Add("Accept-Language", "zh-cn");
                //webrequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; MS-RTC LM 8; Alexa Toolbar)";
                //webrequest.Headers.Add("UA-CPU", "x86");
                //webrequest.KeepAlive = true;
                //HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse();
                //Stream reader = webresponse.GetResponseStream();
                //FileStream writer = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
                //byte[] buff = new byte[1024];
                //int c = 0; //实际读取的字节数
                //while ((c = reader.Read(buff, 0, buff.Length)) > 0)
                //{
                //    writer.Write(buff, 0, c);
                //}
                //writer.Close();
                //writer.Dispose();
                //reader.Close();
                //reader.Dispose();
                //webresponse.Close();
                WebClient mywebclient = new WebClient();
                mywebclient.DownloadFile(url, filePath);
                return "/Upload/Images/BlogContent/" + fileName;
            }
            return url;
            
        }
    }
}
